package com.rbac.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.rbac.exception.BaseException;
import org.springframework.http.HttpStatus;

import java.io.Serializable;

/**
 * api请求返回通用封装
 * @param <T>
 */
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class ApiResponse<T> implements Serializable {


    /**
     * 状态码
     */
    private Integer code;

    /**
     * 返回内容
     */
    private String message;

    /**
     * 返回数据
     */
    private T result;

    /**
     * 全参构造函数
     *
     * @param code    状态码
     * @param message 返回内容
     * @param result  返回数据
     */
    private ApiResponse(Integer code, String message, T result) {
        this.code = code;
        this.message = message;
        this.result = result;
    }

    public ApiResponse() {
        super();
    }

    /**
     * 构造一个自定义的API返回
     *
     * @param code    状态码
     * @param message 返回内容
     * @param result  返回数据
     * @return ApiResponse
     */
    public static <T> ApiResponse<T> of(Integer code, String message, T result) {
        ApiResponse<T> apiResponse = new ApiResponse<>();
        apiResponse.setCode(code);
        apiResponse.setMessage(message);
        apiResponse.setResult(result);
        return apiResponse;
    }

    /**
     * 构造一个成功且不带数据的API返回
     *
     * @return ApiResponse
     */
    public static <T> ApiResponse<T> ofSuccess() {
        return ofSuccess(null);
    }

    /**
     * 构造一个成功且带数据的API返回
     *
     * @param result 返回数据
     * @return ApiResponse
     */
    public static <T> ApiResponse<T> ofSuccess(T result) {
        return ofStatus(HttpStatus.OK, result);
    }

    /**
     * 构造一个成功且自定义消息的API返回
     *
     * @param message 返回内容
     * @return ApiResponse
     */
    public static <T> ApiResponse<T> ofMessage(String message) {
        return of(HttpStatus.OK.value(), message, null);
    }

    /**
     * 构造一个有状态的API返回
     *
     * @param status 状态 {@link HttpStatus}
     * @return ApiResponse
     */
    public static <T> ApiResponse<T> ofStatus(HttpStatus status) {
        return ofStatus(status, null);
    }

    /**
     * 构造一个有状态且带数据的API返回
     *
     * @param status 状态 {@link HttpStatus}
     * @param result 返回数据
     * @return ApiResponse
     */
    public static <T> ApiResponse<T> ofStatus(HttpStatus status, T result) {
        return of(status.value(), status.getReasonPhrase(), result);
    }

    /**
     * 构造一个异常的API返回
     *
     * @param t      异常
     * @param {@link BaseException} 的子类
     * @return ApiResponse
     */
    public <M extends BaseException> ApiResponse<T> ofException(M t) {
        return of(t.getCode(), t.getMessage(), (T) t.getResult());
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getResult() {
        return result;
    }

    public void setResult(T result) {
        this.result = result;
    }

    @Override
    public String toString() {
        return "ApiResponse{" +
                "code=" + code +
                ", message='" + message + '\'' +
                ", result=" +  result.toString()+
                '}';
    }
}

